package com.srdl.code.generate_test;

import com.srdl.code.generate_test.config.DataSourceConfig;
import com.srdl.code.generate_test.config.GlobalConfig;
import com.srdl.code.generate_test.po.TableField;
import com.srdl.code.generate_test.po.TableInfo;
import com.srdl.code.generate_test.utils.CommonUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;


public class CodeGenerate implements ICallBack {

  private static Logger logger = LoggerFactory.getLogger(CodeGenerate.class);


  private List<TableInfo> tableInfoList;
  private TableInfo tableInfo;
  private GlobalConfig globalConfig;
  private DataSourceConfig dataSourceConfig;

    public CodeGenerate() {
    }

    public CodeGenerate(GlobalConfig globalConfig,DataSourceConfig dataSourceConfig)
    {
        this.globalConfig = globalConfig;
        this.dataSourceConfig = dataSourceConfig;
    }

    @Override
    public Map<String, Object> execute() {
        Map data = new HashMap();
        data.put("entityPackage", globalConfig.getPojoPackage());
        data.put("controllerPackage", globalConfig.getControllerPackage());
        data.put("servicePackage", globalConfig.getServicePackage());
        data.put("mapperPackage", globalConfig.getMapperPackage());
        data.put("serviceImplPackage", globalConfig.getServiceImplPackage().replace("/","."));
        data.put("repositoryPackage",globalConfig.getRepositoryPackage());
        //移除表前缀，表名之间的下划线，得到实体类型
        String entity = CommonUtils.getNoUnderlineStr(CommonUtils.removePrefix(tableInfo.getName().toLowerCase(),globalConfig.getPrefix()));
        data.put("entity", StringUtils.capitalize(entity));//实体名称
        data.put("author", globalConfig.getAuthor());//创建作者
        data.put("date",  CommonUtils.getFormatTime("yyyy-MM-dd", new Date() ));//创建时间
        data.put("table", tableInfo);//表信息
        data.put("bao2",globalConfig.getBao());
        data.put("port",globalConfig.getProp());
        data.put("driver",dataSourceConfig.getDriverName());
        data.put("url",dataSourceConfig.getUrl());
        data.put("username",dataSourceConfig.getUsername());
        data.put("password",dataSourceConfig.getPassword());
        String[][] strings=new String[tableInfo.getFields().size()][2];
        if (globalConfig.getType().equals("ssm")){
            List<String> list=new ArrayList<String>();
            List<String> list2=new ArrayList<String>();
            int num=0;
            for (TableField field:tableInfo.getFields()) {
                list.add(field.getName());
                list2.add(field.getName());
                strings[num][0]=CommonUtils.getNoUnderlineStr(field.getName());
                strings[num][1]=field.getName();
                num++;
            }
            data.put("dataCol",list2);//原始列名
            list.remove(0);
            data.put("data2",list);
        }
        data.put("sss",strings);
        boolean isKeyflag = false;
        for (TableField field:tableInfo.getFields()) {
            if(field.isKeyIdentityFlag()){//获取主键字段信息
                data.put("tbKey", field.getName());
                data.put("tbKeyType", field.getPropertyType());
                isKeyflag = true;
                break;
            }
        }
        if(!isKeyflag){
            throw new RuntimeException(String.format("[%s]表缺少主键，不能没有主键",tableInfo.getName()));
        }
        return data;
    }


    /**
     * 生成代码文件
     * @return
     */
    public boolean generateToFile() {
        initConfig();
        if (globalConfig.getType().equals("ssh")){
            for(TableInfo tableInfo : tableInfoList){
                this.tableInfo = tableInfo;//当前需要生成的表
                logger.info("------Code----Generation----[单表模型:" + tableInfo.getName() + "]------- 生成中。。。");
                try{
                    CodeFactory codeFactory = new CodeFactory();
                    codeFactory.setCallBack(this);
                    codeFactory.setGlobalConfig(globalConfig);
                    codeFactory.invoke("ssh/entityTemplate.ftl", "pojo");
                    codeFactory.invoke("ssh/jpaTemplate.ftl", "jpa");
                    codeFactory.invoke("ssh/serviceTemplate.ftl", "service");
                    codeFactory.invoke("ssh/serviceImplTemplate.ftl", "serviceImpl");
                    codeFactory.invoke("ssh/controllerTemplate.ftl", "controller");
                    logger.info("-------Code----Generation-----[单表模型：" + tableInfo.getName() + "]------ 生成完成。。。");
                }catch (Exception e){
                    e.printStackTrace();
                    logger.info("-------Code----Generation-----[单表模型：" + tableInfo.getName() + "]------ 生成失败。。。");
                    return false;
                }
            }
            try{
            logger.info("------Code----Generation----[application.yml]------- 生成中。。。");
            CodeFactory codeFactory = new CodeFactory();
            codeFactory.setCallBack(this);
            codeFactory.setGlobalConfig(globalConfig);
            codeFactory.invoke("ssh/applicationTemplate.ftl","application");
            logger.info("------Code----Generation----[application.yml]------- 生成完成。。。");
            }catch (Exception e){
                e.printStackTrace();
                logger.info("------Code----Generation----[application.yml]------- 生成失败。。。");
                return false;
            }
            try{
                logger.info("------Code----Generation----[Springboot.java]------- 生成中。。。");
                CodeFactory codeFactory = new CodeFactory();
                codeFactory.setCallBack(this);
                codeFactory.setGlobalConfig(globalConfig);
                codeFactory.invoke("ssh/springboot.ftl","springboot");
                logger.info("------Code----Generation----[Springboot.java]------- 生成完成。。。");
            }catch (Exception e){
                e.printStackTrace();
                logger.info("------Code----Generation----[Springboot.java]------- 生成失败。。。");
                return false;
            }
        }

        else if (globalConfig.getType().equals("ssm")){
            for(TableInfo tableInfo : tableInfoList){
                this.tableInfo = tableInfo;//当前需要生成的表
                logger.info("------Code----Generation----[单表模型:" + tableInfo.getName() + "]------- 生成中。。。");
                try{
                    CodeFactory codeFactory = new CodeFactory();
                    codeFactory.setCallBack(this);
                    codeFactory.setGlobalConfig(globalConfig);
                    codeFactory.invoke("ssm/entityTemplate.ftl", "pojo");
                    codeFactory.invoke("ssm/mapperXmlTemplate.ftl", "mapperXml");
                    codeFactory.invoke("ssm/mapperTemplate.ftl", "mapper");
                    codeFactory.invoke("ssm/serviceTemplate.ftl", "service");
                    codeFactory.invoke("ssm/serviceImplTemplate.ftl", "serviceImpl");
                    codeFactory.invoke("ssm/controllerTemplate.ftl", "controller");
                    logger.info("-------Code----Generation-----[单表模型：" + tableInfo.getName() + "]------ 生成完成。。。");
                }catch (Exception e){
                    e.printStackTrace();
                    logger.info("-------Code----Generation-----[单表模型：" + tableInfo.getName() + "]------ 生成失败。。。");
                    return false;
                }
            }
//            try{
//            logger.info("------Code----Generation----[application.yml]------- 生成中。。。");
//            CodeFactory codeFactory = new CodeFactory();
//            codeFactory.setCallBack(this);
//            codeFactory.setGlobalConfig(globalConfig);
//            codeFactory.invoke("ssm/applicationTemplate.ftl","application");
//            logger.info("------Code----Generation----[application.yml]------- 生成完成。。。");
//            }catch (Exception e){
//                e.printStackTrace();
//                logger.info("------Code----Generation----[application.yml]------- 生成失败。。。");
//                return false;
//            }
//            try{
//                logger.info("------Code----Generation----[mybitisConfig.xml]------- 生成中。。。");
//                CodeFactory codeFactory = new CodeFactory();
//                codeFactory.setCallBack(this);
//                codeFactory.setGlobalConfig(globalConfig);
//                codeFactory.invoke("ssm/mybitisConfig.ftl","mybitisConfig");
//                logger.info("------Code----Generation----[mybitisConfig.xml]------- 生成完成。。。");
//            }catch (Exception e){
//                e.printStackTrace();
//                logger.info("------Code----Generation----[mybitisConfig.xml]------- 生成失败。。。");
//                return false;
//            }
//            try{
//                logger.info("------Code----Generation----[Springboot.java]------- 生成中。。。");
//                CodeFactory codeFactory = new CodeFactory();
//                codeFactory.setCallBack(this);
//                codeFactory.setGlobalConfig(globalConfig);
//                codeFactory.invoke("ssm/springboot.ftl","springboot");
//                logger.info("------Code----Generation----[Springboot.java]------- 生成完成。。。");
//            }catch (Exception e){
//                e.printStackTrace();
//                logger.info("------Code----Generation----[Springboot.java]------- 生成失败。。。");
//                return false;
//            }
        }
        return true;
    }

    private void initConfig(){
      if(dataSourceConfig == null){
          throw new RuntimeException("dataSourceConfig is null");
      }
      if(globalConfig == null){
          throw new RuntimeException("globalConfig is null");
      }
      if (globalConfig.getTableNames().length<1) {
          String[] str = new String[dataSourceConfig.getTableNames().size()];
          int num = 0;
          for (String item : dataSourceConfig.getTableNames()) {
              str[num] = item;
              num++;
          }
          globalConfig.setTableNames(str);

      }
          tableInfoList = dataSourceConfig.getTablesInfo(globalConfig.getTableNames());
    }
}
